package com.my.tool.lucky;

import com.my.tool.lucky.model.Gift;
import com.my.tool.lucky.model.MagicBox;
import com.my.tool.lucky.util.MagicNumberTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import	java.util.Random;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

//@Component
public class LuckyLife {

    private Logger logger = LoggerFactory.getLogger(LuckyLife.class);

    public static final int RED_COUNT = 33;
    public static final int BLUE_COUNT = 16;
    public static final int RED_SIZE = 6;
    public static final int BLUE_SIZE = 1;

    private int luckyNum = 7;

    private Random hengMachine = new Random();
    private Random haMachine = new Random();

    private MagicNumberTool magicNumberTool = new MagicNumberTool();

    public Gift doubleBall(int luckyNumber) {
        Gift gift = Gift.of();
        // 6 + 1
        gift.setRed(magicNumberTool.shake(MagicBox.of(luckyNumber, 6, 33, hengMachine, 4, "blue")));
        gift.setBlue(magicNumberTool.shake(MagicBox.of(luckyNumber, 1, 16, haMachine, 1, "red")));
        return gift;
    }

    public Gift lotto(int luckyNumber) {
        Gift gift = Gift.of();
        // 5 + 2
        gift.setRed(magicNumberTool.shake(MagicBox.of(luckyNumber, 5, 35, hengMachine, 4, "blue")));
        gift.setBlue(magicNumberTool.shake(MagicBox.of(luckyNumber, 2, 12, haMachine, 2, "red")));
        return gift;
    }




    public Gift magicPoint0() {
        Gift gift = Gift.of();
        // 幸运红
        gift.setRed(hengRed());
        // 理智蓝
//        gift.setBlue(haBlue(0));
        logger.info("the result, red : {}, blue: {}", gift.getRed(), gift.getBlue());

        return gift;
    }

    private List<Integer> hengRed() {
        logger.info("hello, let us to red boll ... ");
        List<Integer> hengKeys = new ArrayList<>(RED_SIZE);
        for(int hengIndex = 0; hengIndex < RED_SIZE; hengIndex++) {
            int key = hengKey(hengKeys, 0);
            hengKeys.add(key);
            logger.info("hi, the {} red boll is: {}", (hengIndex+1), key);
        }
        logger.info("hello, red boll is ok ... ");
        return hengKeys;
    }

    private int hengKey(List<Integer> hengKeys, int num) {
        int key0 = hengMachine.nextInt(RED_COUNT);
        if(key0==0 || hengKeys.contains(key0)) {
            return hengKey(hengKeys, num);
        }

        List<Integer> black = new ArrayList<>(hengKeys);
        black.add(key0);
        black = black.stream().sorted().collect(Collectors.toList());
        // 检测是否存在连续号4个以上的
        if(checkSerial(black)) {
            return hengKey(hengKeys, num);
        }

        num = num + 1;
        if(num == getLuckyNum()) {
            int key = key0;
            return key;
        }

        return hengKey(hengKeys, num);
    }

    private boolean checkSerial(List<Integer> black) {
        int blackSize = black.size();
        if(blackSize < 4) {
            return false;
        }

        for(int index = 0; index < blackSize - 4; index++) {
            int num1 = black.get(index);
            int num2 = black.get(index + 1);
            int num3 = black.get(index + 2);
            int num4 = black.get(index + 3);

            if(num2-num1==1 && num3-num2==1 && num4-num3==1) {
                return true;
            }
        }
        return false;
    }

    private int haBlue(int num) {
        int key0 = hengMachine.nextInt(BLUE_COUNT);
        if(key0==0) {
            return haBlue(num);
        }

        num = num + 1;
        if(num == getLuckyNum()) {
            int key = key0;
            return key;
        }

        return haBlue(num);
    }

    public int getLuckyNum() {
        return luckyNum;
    }

    public void setLuckyNum(int luckyNum) {
        this.luckyNum = luckyNum;
    }
}
